﻿using System;
using System.Collections;

namespace BizElements.Core
{
    /// <summary>Retrieves and compares entity primary keys using reflection</summary>
    public class EntityKeyBinder : IEntityKeyBinder
    {
        /// <summary>Gets or sets entity.</summary>
        public virtual IEntity EntityWithKey { get; set; }

        /// <summary>
        /// Gets the value(s) that uniquely identify an entity.
        /// In the order as specified in the accompanying IDbTable class.
        /// <b>Null</b> if the parent table/view doesn't have a primary key constraint or the required fields are not set.
        /// </summary>
        /// <returns>An object array that holds Primary Key values.</returns>
        public virtual object[] GetPrimaryKeyValue()
        {
            IEntity entity = this.EntityWithKey;
            DbColumnCollection pkFields = entity.Table.PrimaryKey;
            if (pkFields.Count == 0)
                return null;

            object[] pkValues = new object[pkFields.Count];
            for (int i = 0; i < pkValues.Length; i++)
            {
                object val = ReflectionUtil.GetPublicPropertyValue(entity, pkFields[i].PropertyName);
                if (val == null)
                    return null;

                pkValues[i] = val;
            }

            return pkValues;
        }

        /// <summary>
        /// Checks if the given values are equal to the primary key value of this entity.
        /// </summary>
        /// <param name="values">Values.</param>
        /// <returns>True if primary key values match the given values; false otherwise or if the PK fields 
        /// of this entity aren't set.</returns>
        public virtual bool PrimaryKeyEquals(object[] values)
        {	
            object[] pk = GetPrimaryKeyValue();
            if (pk == null || values == null || pk.Length != values.Length)
                return false;

            for (int valIdx = 0; valIdx < pk.Length; valIdx++)
            {
                if (pk[valIdx].Equals(values[valIdx]) == false)
                    return false;
            }

            return true;
        }
    }
}
